import { _decorator, Button, Component, director, Node, RichText, isValid, sys, Director, AssetManager, AudioClip, resources, assetManager, AudioSource, input, Input, EventKeyboard, KeyCode } from 'cc';
import { Enemy } from './Enemy';
import { L } from './tools/L';
import { SceneManager } from './tools/SceneManager';
import { Cons } from './tools/Cons';
import { Utils } from './tools/Utils';
import { EventAutoManager } from './tools/EventAutoManager';
import { AudioManager } from './tools/AudioManager';
import { ExitGameDialog } from './ExitGameDialog';
const { ccclass, property } = _decorator;
const TAG:string = "GameManager";

@ccclass('GameScene')
export class GameScene extends Component {
    private static _inst: GameScene;
    private _score: number = 0;
    private _bomb: number = 0; 
    private _life: number = 0; 
    
    @property(RichText)
    private scoreRichText: RichText | null = null;
    @property(RichText)
    private bombRichText: RichText | null = null;
    @property(RichText)
    private lifeRichText: RichText | null = null;
    @property(Node)
    private bombUI: Node | null = null;
    @property(Button)
    private pauseButton: Button | null = null;
    @property(Button)
    private resumeButton: Button | null = null;
    
    private _enemyArray: Node[] = [];
    private _eventAutoManager: EventAutoManager = new EventAutoManager();
    // private _soundsBundle: AssetManager.Bundle | null = null;
    
    @property(AudioClip)
    private userBombAudioClip: AudioClip | null = null;
    @property(AudioClip)
    private gameOverAudioClip: AudioClip | null = null;
    @property(AudioClip)
    private gameAudioClip: AudioClip | null = null;
    @property(AudioClip)
    private buttonAudioClip: AudioClip | null = null;
    
    public static get inst(): GameScene {
        return GameScene._inst;
    }


    protected onLoad(): void {
        GameScene._inst = this;
        input.on(Input.EventType.KEY_DOWN, this._onKeyDown, this);
    }

    private _onKeyDown(event: EventKeyboard) {
        if (event.keyCode === KeyCode.ESCAPE) {
            ExitGameDialog.show();
        }
    }
    protected start(): void {
        // this.scoreRichText = Utils.findComponent("Canvas-UI/ScoreText", RichText);
        // this.bombRichText = Utils.findComponent("Canvas-UI/BombUI/CountText", RichText);
        // this.lifeRichText = Utils.findComponent("Canvas-UI/LifeUI/CountText", RichText);
        // this.pauseButton = Utils.findComponent("Canvas-UI/PauseUI", Button);
        // this.resumeButton = Utils.findComponent("Canvas-UI/ResumeUI", Button);
        // this.bombUI = director.getScene()?.getChildByPath("Canvas-UI/BombUI") || null;

        this._eventAutoManager.on(this.bombUI, 'double-click', async () => {
            L.log("双击使用炸弹");
            this.useBomb();
        }, this);

        this._eventAutoManager.on(this.pauseButton?.node, Button.EventType.CLICK, () => {
            AudioManager.inst.playOneShot(this.buttonAudioClip);
            this.pause();
        }, this);

        this._eventAutoManager.on(this.resumeButton?.node, Button.EventType.CLICK, () => {
            AudioManager.inst.playOneShot(this.buttonAudioClip);
            this.resume();
        }, this);
        
        // 初始隐藏继续按钮
        this.resumeButton.node.active = false;
        this.pauseButton.node.active = true;

        AudioManager.inst.play(this.gameAudioClip);

        // assetManager.loadBundle(Cons.BUNDLE.SOUNDS, async (err: Error, bundle: AssetManager.Bundle) => {
        //     if (err) {
        //         L.error(TAG, '加载 Bundle 失败:', err);
        //         return;
        //     }
        //     L.info('Bundle 加载成功');
        //     this._soundsBundle = bundle;

        //     this.userBombAudioClip = await new Promise<AudioClip>((resolve, reject) => {
        //         this._soundsBundle.load("use_bomb", AudioClip, (err, asset) => {
        //             err ? reject(err) : resolve(asset as AudioClip);
        //         });
        //     });

        //     this.gameOverAudioClip = await new Promise<AudioClip>((resolve, reject) => {
        //         this._soundsBundle.load("game_over", AudioClip, (err, asset) => {
        //             err ? reject(err) : resolve(asset as AudioClip);
        //         });
        //     });

        //     this.gameAudioClip = await new Promise<AudioClip>((resolve, reject) => {
        //         this._soundsBundle.load("game_music", AudioClip, (err, asset) => {
        //             err ? reject(err) : resolve(asset as AudioClip);
        //         });
        //     });

        //     this.buttonAudioClip = await new Promise<AudioClip>((resolve, reject) => {
        //         this._soundsBundle.load("button", AudioClip, (err, asset) => {
        //             err ? reject(err) : resolve(asset as AudioClip);
        //         });
        //     });

        //     this.gameAudioClip = await new Promise<AudioClip>((resolve, reject) => {
        //         this._soundsBundle.load("game_music", AudioClip, (err, asset) => {
        //             err ? reject(err) : resolve(asset as AudioClip);
        //         });
        //     });

        //     AudioManager.inst.play(this.gameAudioClip);
        // });
    }

    protected onDestroy(): void {
        // assetManager.releaseAll();
        // this._soundsBundle?.releaseAll();
        this._eventAutoManager.offAll();
        this._enemyArray.length = 0;
        this.unscheduleAllCallbacks();
        input.on(Input.EventType.KEY_DOWN, this._onKeyDown, this);
    }

    private pause(): void {
        director.pause();
        AudioManager.inst.pause();

        //敌机有背景音乐, 也要暂停一下
        for(let enemy of this._enemyArray) {
            const audioSource = enemy.getComponent(AudioSource);
            if(audioSource) {
                audioSource.pause();
            }
        }

        // 初始隐藏继续按钮
        this.resumeButton.node.active = true;
        this.pauseButton.node.active = false;
    }

    private resume(): void {
        director.resume();
        AudioManager.inst.resume();

        //敌机有背景音乐
        for(let enemy of this._enemyArray) {
            const audioSource = enemy.getComponent(AudioSource);
            if(audioSource) {
                audioSource.play();
            }
        }

        // 初始隐藏继续按钮
        this.resumeButton.node.active = false;
        this.pauseButton.node.active = true;
    }

    // ==================== 公有方法 ====================
    public gameOver() {
        AudioManager.inst.playOneShot(this.gameOverAudioClip);
        
        const key = "_history_highest_score_";
        let historyHighestScoreString = sys.localStorage.getItem(key);
        L.debug(`historyHighestScoreString: ${historyHighestScoreString}`);
        let historyHighestScore = 0;
        if (historyHighestScoreString) {
            historyHighestScore = parseInt(historyHighestScoreString);
        }

        if (this._score > historyHighestScore) {
            historyHighestScore = this._score;
            sys.localStorage.setItem(key, `${historyHighestScore}`);
        }
        this.scheduleOnce(() => {
            SceneManager.inst.loadScene(Cons.SCENES.GAME_OVER, { historyHighestScore, score: this._score });
        }, 1 / 1000)
    }

    public isPaused(): boolean {
        return director.isPaused();
    }

    public set life(life: number) {
        this._life = life;
        this.lifeRichText.string = `${this._life}`;
    }

    public addScore(score: number): void {
        this._score += score;
        this.scoreRichText.string = `${this._score}`;
    }

    public canUseBomb(): boolean {
        return this._bomb > 0;
    }

    public useBomb() {
        if (!this.canUseBomb()) return;
        AudioManager.inst.playOneShot(this.userBombAudioClip);

        this.addBomb(-1);
        this._enemyArray.forEach(node => {
            node.getComponent(Enemy)?.killNow();
        });
    }

    public addBomb(bomb: number): void {
        this._bomb += bomb;
        this.bombRichText.string = `${this._bomb}`;
    }

    public addEnemy(node: Node): void {
        if (node && isValid(node)) {
            this._enemyArray.push(node);
        }
    }

    public removeEnemy(node: Node): void {
        const index = this._enemyArray.indexOf(node);
        if (index !== -1) {
            this._enemyArray.splice(index, 1);
            L.debug(`删除敌机 ${node.name} - ${node.uuid}, 当前敌机数: ${this._enemyArray.length}`);
        }
    }
}